#ifndef UPDATER_H
#define UPDATER_H

#include <QNetworkAccessManager>
#include <QDomDocument>
#include <QUrl>
#include <QDir>
#include <QDialog>
#include <QMutex>
#include <QEventLoop>

struct Version
{
    enum License
    {
        Free
    };

    Version();

    void read(const QDomElement & element);
    void write(QDomElement * element);

    bool operator ==(const Version & ver) const;

    License license;
    int version;
    int build;
};

bool operator >(const Version & ver1, const Version & ver2);
bool operator <(const Version & ver1, const Version & ver2);

struct UpdateItem
{
    bool read(const QDomElement & element);

    QUrl url;
    QString path;
};

typedef QList<UpdateItem> UpdateItemList;

struct Update
{
    bool read(const QDomElement & element);
    bool execute();

    Version version;
    UpdateItemList itemList;
};

typedef QList<Update> UpdateList;

class Updater : public QObject
{
    Q_OBJECT

public:
    enum License
    {
        Free
    };

    Updater(QObject * parent = 0);

    bool readVersionInfo();
    bool checkNeedUpdate();
    bool update();

public slots:
    void updatesInfoDownloadFinished(QNetworkReply * reply);
    void downloadFinished(QNetworkReply * reply);

private:
    bool downloadUpdatesInfo();
    void removeOldUpdates();
    QNetworkReply * downloadUpdateItem(const UpdateItem & item);
    bool executeUpdateItem(QNetworkReply * reply, const UpdateItem & item);
    void updateVersionInfo();
    void createUpdateItemsList();

    QNetworkAccessManager m_manager;
    Version m_currectVersion;
    UpdateList m_updateList;
    UpdateItemList m_updateItemList;
    QEventLoop m_downloadEventLoop;
};

class UpdateDialog : public QDialog
{
    Q_OBJECT

public:
    UpdateDialog();
};

#endif // UPDATER_H
